// $Id: test_cache.cpp 9 2008-09-30 03:21:47Z rodlima $

#define BOOST_TEST_MODULE cache
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <climits>
#include <boost/test/unit_test.hpp>
#include <cache.h>
#include <metainfo.h>

using namespace orm;

struct Teste : object<Teste>/*{{{*/
{
    Teste(Teste &&that) 
        : object<Teste>(std::move(that))
        , dados(std::move(that.dados))
        , name(std::move(that.name)) {}

    Teste(ident id=0) : object<Teste>(id) {}
    std::vector<int> dados;
    std::string name;

    static metainfo<Teste> meta;
};
metainfo<Teste> Teste::meta = metainfo<Teste>("Teste")
                                .ident("idteste")
                                .member(&Teste::name, "name");
/*}}}*/


BOOST_AUTO_TEST_CASE(cache_update_novo)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    std::shared_ptr<const Teste> objcache = c.update(obj).lock();

    BOOST_REQUIRE_EQUAL((bool)objcache, true);
    BOOST_CHECK_EQUAL(obj.in_cache(), false);
    BOOST_CHECK_EQUAL(objcache->in_cache(), true);

    std::shared_ptr<const Teste> added = c.get<Teste>(obj.id).lock();
    BOOST_REQUIRE_EQUAL((bool)added, true);
    BOOST_CHECK_EQUAL(added->in_cache(), true);
    BOOST_CHECK_EQUAL(added.get(), objcache.get());

    std::unique_ptr<Teste> objclone = objcache->clone();
    BOOST_CHECK_EQUAL(objclone->in_cache(), false);

    BOOST_CHECK_EQUAL(*objcache, obj);
}/*}}}*/
BOOST_AUTO_TEST_CASE(cache_update_jah_existe_igual)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    c.update(obj);

    c.update(obj);
    BOOST_CHECK_EQUAL(*c.get<Teste>(obj.id).lock(), obj);
}/*}}}*/
BOOST_AUTO_TEST_CASE(cache_update_jah_existe_diferente)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    c.update(obj);

    obj.name = "dois";

    c.update(obj);
    BOOST_CHECK_EQUAL(*c.get<Teste>(obj.id).lock(), obj);
}/*}}}*/
BOOST_AUTO_TEST_CASE(cache_get_obj)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    c.update(obj);

    BOOST_CHECK_EQUAL(*c.get(obj).lock(), obj);
}/*}}}*/
BOOST_AUTO_TEST_CASE(cache_update)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    c.update(obj);

    Teste obj2(1);
    obj2.name = "dois";
    std::shared_ptr<const Teste> tst = c.update(obj2).lock();
    BOOST_REQUIRE_EQUAL((bool)tst, true);
    BOOST_CHECK_EQUAL(tst->in_cache(), true);
    BOOST_CHECK_EQUAL(obj2.in_cache(), false);

    BOOST_CHECK_EQUAL(*c.get<Teste>(obj2.id).lock(), obj2);
}/*}}}*/
BOOST_AUTO_TEST_CASE(cache_rem)/*{{{*/
{
    cache c;

    Teste obj(1);
    obj.name = "um";
    c.update(obj);

    Teste obj2(1);
    obj2.name = "dois";
    c.update(obj2);

    std::shared_ptr<const Teste> objcache = c.get<Teste>(obj2.id).lock();

    c.rem(obj2);
    BOOST_CHECK_EQUAL(objcache->in_cache(), false);

    BOOST_CHECK_EQUAL(c.get<Teste>(obj2.id).expired(), true);
}/*}}}*/

